import { Request, Response } from 'express';
import { PrismaClient, LocationStatus } from '@prisma/client';
import { ResponseHelper } from '../utils/response';

const prisma = new PrismaClient();

/**
 * 创建地点请求体接口
 */
interface CreateLocationBody {
  name: string;
  coordinateX: number;
  coordinateY: number;
}

/**
 * 更新地点请求体接口
 */
interface UpdateLocationBody {
  name?: string;
  coordinateX?: number;
  coordinateY?: number;
  adminNote?: string;
}

/**
 * 获取地点列表
 * GET /api/v1/locations
 * 支持查询参数：status(PENDING|APPROVED|REJECTED), page, limit
 */
export const getLocations = async (req: Request, res: Response): Promise<void> => {
  try {
    const { status, page = '1', limit = '20' } = req.query;

    const pageNum = parseInt(page as string, 10);
    const limitNum = parseInt(limit as string, 10);
    const skip = (pageNum - 1) * limitNum;

    // 构建查询条件
    const where: any = {};
    if (status && ['PENDING', 'APPROVED', 'REJECTED'].includes(status as string)) {
      where.status = status as LocationStatus;
    }

    // 查询地点列表（包含评分统计）
    const locations = await prisma.location.findMany({
      where,
      skip,
      take: limitNum,
      include: {
        creator: {
          select: {
            id: true,
            nickname: true,
            avatarUrl: true
          }
        },
        ratings: {
          select: {
            score: true
          }
        },
        _count: {
          select: {
            ratings: true,
            recommendedDishes: true
          }
        }
      },
      orderBy: {
        createdAt: 'desc'
      }
    });

    // 计算平均评分
    const locationsWithAvgRating = locations.map(location => {
      const totalScore = location.ratings.reduce((sum, r) => sum + r.score, 0);
      const avgRating = location.ratings.length > 0 ? totalScore / location.ratings.length : 0;

      const { ratings, ...locationData } = location;

      return {
        ...locationData,
        avgRating: parseFloat(avgRating.toFixed(1)),
        ratingsCount: location._count.ratings,
        dishesCount: location._count.recommendedDishes
      };
    });

    // 查询总数
    const total = await prisma.location.count({ where });

    ResponseHelper.paginated(
      res,
      locationsWithAvgRating,
      {
        page: pageNum,
        limit: limitNum,
        total,
        totalPages: Math.ceil(total / limitNum)
      },
      '获取成功'
    );

  } catch (error: any) {
    console.error('获取地点列表失败:', error);
    ResponseHelper.serverError(res, '获取地点列表失败', error);
  }
};

/**
 * 获取地点详情
 * GET /api/v1/locations/:id
 */
export const getLocationById = async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const locationId = parseInt(id, 10);

    if (isNaN(locationId)) {
      ResponseHelper.validationError(res, [
        { field: 'id', message: '无效的地点ID' }
      ]);
      return;
    }

    const location = await prisma.location.findUnique({
      where: { id: locationId },
      include: {
        creator: {
          select: {
            id: true,
            nickname: true,
            avatarUrl: true
          }
        },
        ratings: {
          select: {
            id: true,
            score: true,
            userId: true,
            createdAt: true,
            user: {
              select: {
                nickname: true,
                avatarUrl: true
              }
            }
          },
          orderBy: {
            createdAt: 'desc'
          }
        },
        recommendedDishes: {
          select: {
            id: true,
            dishName: true,
            floor: true,
            price: true,
            createdAt: true,
            user: {
              select: {
                nickname: true,
                avatarUrl: true
              }
            }
          },
          orderBy: {
            createdAt: 'desc'
          }
        },
        congestionLevels: {
          select: {
            timePeriod: true,
            level: true,
            updatedAt: true
          }
        }
      }
    });

    if (!location) {
      ResponseHelper.notFound(res, '地点不存在');
      return;
    }

    // 计算平均评分
    const totalScore = location.ratings.reduce((sum, r) => sum + r.score, 0);
    const avgRating = location.ratings.length > 0 ? totalScore / location.ratings.length : 0;

    const result = {
      ...location,
      avgRating: parseFloat(avgRating.toFixed(1)),
      ratingsCount: location.ratings.length,
      dishesCount: location.recommendedDishes.length
    };

    ResponseHelper.success(res, result, '获取成功');

  } catch (error: any) {
    console.error('获取地点详情失败:', error);
    ResponseHelper.serverError(res, '获取地点详情失败', error);
  }
};

/**
 * 创建地点
 * POST /api/v1/locations
 * 需要JWT认证
 * 管理员创建的地点自动审核通过，普通用户创建的地点需要审核
 */
export const createLocation = async (req: Request, res: Response): Promise<void> => {
  try {
    if (!req.user) {
      ResponseHelper.unauthorized(res, '请先登录');
      return;
    }

    const { name, coordinateX, coordinateY } = req.body as CreateLocationBody;

    // 验证必填参数
    if (!name || coordinateX === undefined || coordinateY === undefined) {
      ResponseHelper.validationError(res, [
        ...(!name ? [{ field: 'name', message: '地点名称不能为空' }] : []),
        ...(coordinateX === undefined ? [{ field: 'coordinateX', message: 'X坐标不能为空' }] : []),
        ...(coordinateY === undefined ? [{ field: 'coordinateY', message: 'Y坐标不能为空' }] : [])
      ]);
      return;
    }

    // 验证坐标格式
    if (typeof coordinateX !== 'number' || typeof coordinateY !== 'number') {
      ResponseHelper.validationError(res, [
        { field: 'coordinates', message: '坐标必须是数字类型' }
      ]);
      return;
    }

    // 根据用户角色设置状态
    const status: LocationStatus = req.user.role === 'ADMIN' ? 'APPROVED' : 'PENDING';

    // 创建地点
    const location = await prisma.location.create({
      data: {
        name,
        coordinateX,
        coordinateY,
        status,
        creatorId: req.user.id
      },
      include: {
        creator: {
          select: {
            id: true,
            nickname: true,
            avatarUrl: true
          }
        }
      }
    });

    const message = status === 'APPROVED'
      ? '地点创建成功'
      : '地点已提交，等待管理员审核';

    ResponseHelper.success(res, location, message, 201);

  } catch (error: any) {
    console.error('创建地点失败:', error);
    ResponseHelper.serverError(res, '创建地点失败', error);
  }
};

/**
 * 更新地点信息
 * PUT /api/v1/locations/:id
 * 需要JWT认证，仅创建者或管理员可更新
 */
export const updateLocation = async (req: Request, res: Response): Promise<void> => {
  try {
    if (!req.user) {
      ResponseHelper.unauthorized(res, '请先登录');
      return;
    }

    const { id } = req.params;
    const locationId = parseInt(id, 10);

    if (isNaN(locationId)) {
      ResponseHelper.validationError(res, [
        { field: 'id', message: '无效的地点ID' }
      ]);
      return;
    }

    // 检查地点是否存在
    const existingLocation = await prisma.location.findUnique({
      where: { id: locationId }
    });

    if (!existingLocation) {
      ResponseHelper.notFound(res, '地点不存在');
      return;
    }

    // 权限检查：仅创建者或管理员可更新
    if (existingLocation.creatorId !== req.user.id && req.user.role !== 'ADMIN') {
      ResponseHelper.forbidden(res, '无权修改此地点');
      return;
    }

    const { name, coordinateX, coordinateY, adminNote } = req.body as UpdateLocationBody;

    // 构建更新数据
    const updateData: any = {};
    if (name !== undefined) updateData.name = name;
    if (coordinateX !== undefined) updateData.coordinateX = coordinateX;
    if (coordinateY !== undefined) updateData.coordinateY = coordinateY;

    // 仅管理员可以修改备注
    if (adminNote !== undefined && req.user.role === 'ADMIN') {
      updateData.adminNote = adminNote;
    }

    // 更新地点
    const location = await prisma.location.update({
      where: { id: locationId },
      data: updateData,
      include: {
        creator: {
          select: {
            id: true,
            nickname: true,
            avatarUrl: true
          }
        }
      }
    });

    ResponseHelper.success(res, location, '更新成功');

  } catch (error: any) {
    console.error('更新地点失败:', error);
    ResponseHelper.serverError(res, '更新地点失败', error);
  }
};

/**
 * 删除地点
 * DELETE /api/v1/locations/:id
 * 需要JWT认证，仅创建者或管理员可删除
 */
export const deleteLocation = async (req: Request, res: Response): Promise<void> => {
  try {
    if (!req.user) {
      ResponseHelper.unauthorized(res, '请先登录');
      return;
    }

    const { id } = req.params;
    const locationId = parseInt(id, 10);

    if (isNaN(locationId)) {
      ResponseHelper.validationError(res, [
        { field: 'id', message: '无效的地点ID' }
      ]);
      return;
    }

    // 检查地点是否存在
    const existingLocation = await prisma.location.findUnique({
      where: { id: locationId }
    });

    if (!existingLocation) {
      ResponseHelper.notFound(res, '地点不存在');
      return;
    }

    // 权限检查：仅创建者或管理员可删除
    if (existingLocation.creatorId !== req.user.id && req.user.role !== 'ADMIN') {
      ResponseHelper.forbidden(res, '无权删除此地点');
      return;
    }

    // 删除地点（级联删除关联的评分、推荐菜品和拥堵程度）
    await prisma.location.delete({
      where: { id: locationId }
    });

    ResponseHelper.success(res, null, '删除成功');

  } catch (error: any) {
    console.error('删除地点失败:', error);
    ResponseHelper.serverError(res, '删除地点失败', error);
  }
};

/**
 * 审核通过地点
 * PUT /api/v1/locations/:id/approve
 * 需要JWT认证和管理员权限
 */
export const approveLocation = async (req: Request, res: Response): Promise<void> => {
  try {
    if (!req.user) {
      ResponseHelper.unauthorized(res, '请先登录');
      return;
    }

    if (req.user.role !== 'ADMIN') {
      ResponseHelper.forbidden(res, '仅管理员可审核地点');
      return;
    }

    const { id } = req.params;
    const locationId = parseInt(id, 10);

    if (isNaN(locationId)) {
      ResponseHelper.validationError(res, [
        { field: 'id', message: '无效的地点ID' }
      ]);
      return;
    }

    // 检查地点是否存在
    const existingLocation = await prisma.location.findUnique({
      where: { id: locationId }
    });

    if (!existingLocation) {
      ResponseHelper.notFound(res, '地点不存在');
      return;
    }

    // 更新状态为已通过
    const location = await prisma.location.update({
      where: { id: locationId },
      data: { status: 'APPROVED' },
      include: {
        creator: {
          select: {
            id: true,
            nickname: true,
            avatarUrl: true
          }
        }
      }
    });

    ResponseHelper.success(res, location, '审核通过');

  } catch (error: any) {
    console.error('审核地点失败:', error);
    ResponseHelper.serverError(res, '审核地点失败', error);
  }
};

/**
 * 拒绝地点
 * PUT /api/v1/locations/:id/reject
 * 需要JWT认证和管理员权限
 */
export const rejectLocation = async (req: Request, res: Response): Promise<void> => {
  try {
    if (!req.user) {
      ResponseHelper.unauthorized(res, '请先登录');
      return;
    }

    if (req.user.role !== 'ADMIN') {
      ResponseHelper.forbidden(res, '仅管理员可审核地点');
      return;
    }

    const { id } = req.params;
    const locationId = parseInt(id, 10);

    if (isNaN(locationId)) {
      ResponseHelper.validationError(res, [
        { field: 'id', message: '无效的地点ID' }
      ]);
      return;
    }

    // 检查地点是否存在
    const existingLocation = await prisma.location.findUnique({
      where: { id: locationId }
    });

    if (!existingLocation) {
      ResponseHelper.notFound(res, '地点不存在');
      return;
    }

    // 更新状态为已拒绝
    const location = await prisma.location.update({
      where: { id: locationId },
      data: { status: 'REJECTED' },
      include: {
        creator: {
          select: {
            id: true,
            nickname: true,
            avatarUrl: true
          }
        }
      }
    });

    ResponseHelper.success(res, location, '已拒绝');

  } catch (error: any) {
    console.error('拒绝地点失败:', error);
    ResponseHelper.serverError(res, '拒绝地点失败', error);
  }
};
